﻿using MarriageFertility.Helpers;
using TaleWorlds.CampaignSystem.Encounters;
using System.Linq;
using TaleWorlds.CampaignSystem;
using TaleWorlds.Core;
using TaleWorlds.InputSystem;
using TaleWorlds.Library;
using TaleWorlds.MountAndBlade;

namespace MarriageFertility.Missions;

internal class DuelSingleMissionLogic : MissionLogic
{
    private readonly bool _spawnBothSidesWithHorses;
    private readonly bool _friendlyDuel;
    private readonly bool _isInsideSettlement;

    private BasicMissionTimer _duelEndTimer;
    private Agent _duelAgent;
    private bool _duelHasEnded;
    private bool _duelWon;

    public DuelSingleMissionLogic(bool spawnBothSidesWithHorses, bool friendlyDuel, bool isInsideSettlement)
    {
        _spawnBothSidesWithHorses = spawnBothSidesWithHorses;
        _friendlyDuel = friendlyDuel;
        _isInsideSettlement = isInsideSettlement;
    }

    public override void AfterStart()
    {
        SetupMission();
        SetupAgents();
    }

    private void SetupMission()
    {
        Mission.SetMissionMode(MissionMode.Duel, true);
        _duelHasEnded = false;
        _duelEndTimer = new BasicMissionTimer();
        InitializeMissionTeams();
    }

    private void SetupAgents()
    {
        (MatrixFrame playerSpawnFrame, MatrixFrame opponentSpawnFrame) =
            _isInsideSettlement ? MissionHelper.GetArenaSpawnFrames() : MissionHelper.GetBattleSpawnFrames();
        MissionHelper.SpawnAgent(CharacterObject.PlayerCharacter, playerSpawnFrame, true, _friendlyDuel,
            _spawnBothSidesWithHorses);
        _duelAgent = MissionHelper.SpawnAgent(DuelManager.DuelHero, opponentSpawnFrame, false, _friendlyDuel,
            _spawnBothSidesWithHorses);
        Mission.CameraIsFirstPerson = false;
    }

    public override void OnMissionTick(float dt)
    {
        if (_duelHasEnded && _duelEndTimer.ElapsedTime > 4.0)
        {
            DisplayDuelEndInformation();
            _duelEndTimer.Reset();
        }
    }

    private void DisplayDuelEndInformation()
    {
        var leaveKeyText = Game.Current.GameTextManager.GetHotKeyGameTextFromKeyID(
            HotKeyManager.GetAllCategories()
                .FirstOrDefault(r => r.GameKeyCategoryId == "Generic")?
                .RegisteredGameKeys[4].KeyboardKey.ToString());

        GameTexts.SetVariable("leave_key", leaveKeyText.ToString());
        MBInformationManager.AddQuickInformation(GameTexts.FindText("str_duel_has_ended"));
    }

    public override InquiryData OnEndMissionRequest(out bool canLeave)
    {
        canLeave = true;
        return _duelHasEnded
            ? null
            : new InquiryData("", GameTexts.FindText("str_give_up_fight").ToString(), true, true,
                GameTexts.FindText("str_ok").ToString(), GameTexts.FindText("str_cancel").ToString(),
                Mission.OnEndMissionResult, null);
    }

    public override void OnAgentRemoved(Agent affectedAgent, Agent affectorAgent, AgentState agentState,
        KillingBlow killingBlow)
    {
        if (affectedAgent.IsHuman)
        {
            _duelHasEnded = true;
            _duelWon = affectedAgent == _duelAgent;
        }
    }

    protected override void OnEndMission()
    {
        DuelManager.SetDuelMissionResult(_duelWon);
        DuelManager.CallBackEndEvent(_duelWon);
        PlayerEncounter.Finish();
    }


    private void InitializeMissionTeams()
    {
        Mission.Teams.Add(BattleSideEnum.Defender, Hero.MainHero.MapFaction.Color, Hero.MainHero.MapFaction.Color2,
            Hero.MainHero.Clan.Banner);
        Mission.Teams.Add(BattleSideEnum.Attacker, DuelManager.DuelHero.Culture.Color,
            DuelManager.DuelHero.Culture.Color2, DuelManager.DuelHero.HeroObject?.Clan?.Banner);
        Mission.PlayerTeam = Mission.DefenderTeam;
    }
}